﻿using System;
using System.Web.Mvc;

namespace PRGexample
{
	public abstract class ModelStateResultTempDataTransferAttribute : ActionFilterAttribute
	{
		protected static readonly string Key = typeof( ModelStateResultTempDataTransferAttribute).FullName;
	}

	public class ExportModelStateResultToTempDataAttribute :  ModelStateResultTempDataTransferAttribute
	{
		private readonly string successMessage = string.Empty;

		public ExportModelStateResultToTempDataAttribute() { }

		public ExportModelStateResultToTempDataAttribute(string successMessage)	{ this.successMessage = successMessage;}
		public override void OnActionExecuted(ActionExecutedContext filterContext)
		{
			//Export if we are redirecting
			if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
			{
				var modelState = filterContext.Controller.ViewData.ModelState;

				var redirectedModelState = new RedirectedModelState();

				if (!modelState.IsValid)
				{
					redirectedModelState.ModelState = modelState;
				}
				else if (!string.IsNullOrEmpty(successMessage))
				{
					redirectedModelState.SuccessMessage = this.successMessage;
				}

				filterContext.Controller.TempData[Key] = redirectedModelState;
			}

			base.OnActionExecuted(filterContext);
		}
	}

	public class ImportModelStateResultFromTempDataAttribute :  ModelStateResultTempDataTransferAttribute
	{

		public ImportModelStateResultFromTempDataAttribute() { }
				
		public override void OnActionExecuted(ActionExecutedContext filterContext)
		{
			var redirectedModelState = filterContext.Controller.TempData[Key] as RedirectedModelState;

			if (redirectedModelState != null)
			{
				//Only Import if we are viewing
				if (filterContext.Result is ViewResult)
				{
					filterContext.Controller.ViewData.ModelState.Merge(redirectedModelState.ModelState);
					filterContext.Controller.ViewBag.Success = redirectedModelState.SuccessMessage;

				}

				filterContext.Controller.TempData.Remove(Key);
			}

			base.OnActionExecuted(filterContext);
		}
	}

	[Serializable]
	public class RedirectedModelState
	{
		public ModelStateDictionary ModelState { get; set; }

		public string SuccessMessage { get; set; }
	}
}